package com.cmeduSystem.common.flow.listener;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.cmeduSystem.common.core.util.ApplicationContextHolder;
import com.cmeduSystem.common.flow.constant.FlowConstant;
import com.cmeduSystem.common.flow.model.FlowEntry;
import com.cmeduSystem.common.flow.object.FlowBusinessOperationConfig;
import com.cmeduSystem.common.flow.object.FlowEntryExtensionData;
import com.cmeduSystem.common.flow.service.FlowEntryService;
import com.cmeduSystem.common.flow.util.FlowBusinessHelper;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;

import java.util.List;

/**
 * 流程实例业务数据操作的监听器，主要用于流程实例发起或结束后和业务表数据的交互。
 *
 * @author xulei
 * @date 2025-09-04
 */
@Slf4j
public class FlowBusinessOperationListener implements ExecutionListener {

    private final transient FlowEntryService flowEntryService =
            ApplicationContextHolder.getBean(FlowEntryService.class);
    private final transient FlowBusinessHelper flowBusinessHelper =
            ApplicationContextHolder.getBean(FlowBusinessHelper.class);

    @Override
    public void notify(DelegateExecution e) {
        FlowEntry flowEntry = flowEntryService.getFlowEntryByProcessDefinitionId(e.getProcessDefinitionId());
        FlowEntryExtensionData extensionData =
                JSONObject.parseObject(flowEntry.getExtensionData(), FlowEntryExtensionData.class);
        if (StrUtil.isBlank(extensionData.getProcessBusinessOperations())) {
            return;
        }
        List<FlowBusinessOperationConfig> configs =
                JSONObject.parseArray(extensionData.getProcessBusinessOperations(), FlowBusinessOperationConfig.class);
        String eventType = StrUtil.equals("start", e.getEventName())
                ? FlowConstant.EVENT_TYPE_START_FLOW : FlowConstant.EVENT_TYPE_END_FLOW;
        FlowBusinessOperationConfig config = configs.stream()
                .filter(c -> StrUtil.equals(c.getOperationType(), eventType))
                .findFirst().orElse(null);
        if (config == null) {
            return;
        }
        JSONObject variableData = flowBusinessHelper.getNonRealtimeSystemVariables();
        variableData.putAll(e.getVariables());
        flowBusinessHelper.executeBusinessOperation(config, e.getId(), null, variableData);
    }
}
